#include "video.h"
#include <io.h>
#include <system/mod.h>

module_t video_module =
{
	.name = "video\0",
	.author = "dak\0",
	.license = "gpl\0",
	.desc = "standard video output\0",
	.dep = "\0",
	.type = MOD_TYPE_SYSTEM,
	
	.init = video_init,
	.shut = video_shut,
};


uint32_t video_init()
{
	
}

uint32_t video_shut()
{
	
}


/*
 *  Disegna una lettera nello schermo
 */
void video_put(char ch)
{
	char *vidmem = (char *) VIDEO_MEM;
	unsigned int i = 0;
	int x;

	// Calcola la posizione nel buffer video
	i = (video_cursor_y * VIDEO_COLS * 2) + (video_cursor_x * 2);
	
	// Esaminiamo il carattere
	switch(ch)
	{
		// A capo
		case '\n':
			video_cursor_y++;
			video_cursor_x = 0;
			break;
		
		// Tab
		case '\t':
			for(x = 0; x < VIDEO_TAB_DIM; x++)
				video_put(' ');
			break;

		// Carattere normale
		default:
			vidmem[i] = ch;
			i++;
			vidmem[i] = video_attr;
			video_cursor_x++;
			break;
	}


	// Controlla se le posizioni x e y hanno superato i limiti
	if(video_cursor_y >= VIDEO_LINES)
		video_scrool_dw();
		
	if(video_cursor_x >= VIDEO_COLS)
	{
		video_cursor_y++;
		video_cursor_x = 0;
	}


	// Riposiziona il cursore
	video_move_cursor(video_cursor_x, video_cursor_y); 
}


/*
 *  Visualizza uno stream di caratteri fino a '\0'
 */
void video_puts(char *str)
{
	while(*str != '\0')
	{
		video_put(*str);
		str++;
	}
}

/*
 *  Muove il cursore in un punto x y dello schermo
 */
void video_move_cursor(int x, int y)
{
	unsigned short position=(x*VIDEO_COLS) + y;

	// cursor LOW port to vga INDEX register
	//io_out(0x3D4, 0x0F);
	//io_out(0x3D5, (unsigned char)(position&0xFF));
	// cursor HIGH port to vga INDEX register
	//io_out(0x3D4, 0x0E);
	//io_out(0x3D5, (unsigned char )((position>>8)&0xFF));
	//io_out(0x3D4, 0x0E);                  // Tell the VGA board we are setting the high cursor byte.
	//io_out(0x3D5, (char) (position >> 8)); // Send the high cursor byte.
	//io_out(0x3D4, 0x0F);                  // Tell the VGA board we are setting the low cursor byte.
	//io_out(0x3D5, position);
	
}


/*
 *  Cancella l'intero schermo
 */
void video_clear()
{
	unsigned char *vidmem = (unsigned char *) VIDEO_MEM;
	int i = 0;

	while(i < (VIDEO_COLS * VIDEO_LINES * 2))
	{
		vidmem[i] = ' ';
		i++;
		vidmem[i] = video_attr;
		i++;
	}
	video_gotoxy(0,0);
}



/*
 *  Setta gli attributi del colore
 */ 
void video_set_attr(char at)
{
	video_attr = at;
}



/*
 *  Restituisce gli attributi del colore in uso
 */
char video_get_attr()
{
	return video_attr;
}


/*
 *  Si sposta alle coordinate x y
 */
void video_gotoxy(int x, int  y)
{
	video_move_cursor(x,y);
	video_cursor_x = x;
	video_cursor_y = y;
}


/*
 *  Restituisce  x o y
 */
int video_get_x()
{
	return video_cursor_x;
}


int video_get_y()
{
	return video_cursor_y;
}


int video_get_dimx()
{
	return VIDEO_COLS;
}


int video_get_dimy()
{
	return VIDEO_LINES;
}




/*
 *  Scrolla lo schermo verso il basso
 */
void video_scrool_dw()
{
	char *vidmem = (char *) VIDEO_MEM;
	
	unsigned int x;
	unsigned int y;
	unsigned int i;
	unsigned int j;
	
	
	for(x = 0; x < VIDEO_COLS; x++)
	{
		for(y = 0; y <= VIDEO_LINES; y++)
		{
			i = (y * VIDEO_COLS * 2) + (x * 2);
			j = ((y+1) * VIDEO_COLS * 2) + (x * 2);
			vidmem[i] = vidmem[j];
			i++; j++;
			vidmem[i] = vidmem[j];
 		}
	}
	
	//video_gotoxy(0,VIDEO_LINES);
	//for(x = 0; x < VIDEO_COLS-1; x++)
	//	video_put(' ');
	//video_gotoxy(0,VIDEO_LINES-1);
	video_cursor_y--;	
}



/*
 *  Draw colored string
 */
void video_color_puts(char col, char *string)
{
	char x = video_get_attr();	
	video_set_attr(col);
	video_puts(string);
	video_set_attr(x);
}

